home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / VGOVBE20.ZIP / VGOVBE20.TXT < prev   
Text File  |  1997-03-24  |  24KB  |  543 lines

  1.  
  2. ─────────────────────────────────────────────────────────────────────────────
  3.  
  4.   VGOVBE20.TXT - Vesa 2.0 implementation, activation, and just plain how
  5.                  it works.                 
  6.  
  7. ─────────────────────────────────────────────────────────────────────────────
  8.  
  9.   Doc  by: Vector/Vertigo
  10.   Code by: TimJ/Vertigo
  11.  
  12.   If I were TimJ a quote would go here....
  13.  
  14.   Vertigo Webpage = http://demoscene.interstat.net/~vertigo/
  15.  
  16.   email: tim@legend.co.uk      = TimJ
  17.          cowan@gold.guate.net  = Vector
  18.   irc:   #coders #vertcode
  19.  
  20.  
  21.   revision history:
  22.  
  23.   24/03/97      v1.0    -       Initial version
  24.  
  25.  
  26. ─────────────────────────────────────────────────────────────────────────────
  27.  INTRODUCTION
  28. ─────────────────────────────────────────────────────────────────────────────
  29.  
  30.    Well, it's been about a month since TimJ released vgophong.doc, and we
  31. decided it was time to release a few more tutorials (two in fact). These
  32. tutorials should be pretty messed up, since I am writing a tutorial on
  33. TimJ's Vesa code, and he is writing one on my faith code ;).
  34.  
  35.    The reason of this tut is because lately the trend has been moving on to
  36. Vesa 2.0. Vesa 2.0 is a standard that enables all cards to be able to do
  37. certain acts, using the same exact functions. These commands are quite basic,
  38. but very powerful. One can use high resolutions and high colors, just as easy
  39. as writing to the normal VGA mode 13h.
  40.  
  41.    Unfortunately, there is no good documentation out there on how to set
  42. the Vesa 2.0 modes ( which are a little harder to set than mode 13h ;).
  43. There are a few libraries out there that give the user the functions to set
  44. Vesa 2.0.  But obviously most people out there don't want to have to kludge
  45. in someone elses libraries just to use this. Also, many people who do manage
  46. to set the modes, notice that for some reason their code is very buggy.
  47. This is usually because they forgot to set LFB, remap the LFB, check to see
  48. if the mode is available, or even if they are setting the right mode.
  49.  
  50.  
  51. ─────────────────────────────────────────────────────────────────────────────
  52.  BEFORE WE START
  53. ─────────────────────────────────────────────────────────────────────────────
  54.  
  55.    This TXT assumes that you have knowledge of working with VGA mode 13h and
  56. protected mode. Also, some knowledge of assembler would be beneficial =).
  57. The PMode Header you use MUST support DPMI function 800h. (DOS32 Free Version
  58. does not=( ).
  59.    If you want to use the included source, you should have an assembler (it
  60. has been tested with TASM 3.1 and TASM 5.0). But just in case, I have also
  61. included an .OBJ file.  Also included is a C header file,  so that this may
  62. be included in your C/C++ programs. Finnally, a 2 short C programs have been
  63. included, to show a bit on the use of the code (They have been tested with
  64. Watcom C 10.5a and 10.6).
  65.    Also, This Document and its companion code is provided free, and as-is.
  66. Put all that other disclaimer junk here too... oh, if any harm comes to your
  67. machine from this, then send flames to president@whitehouse.gov . We are not
  68. responsible =).
  69.  
  70.  
  71. ─────────────────────────────────────────────────────────────────────────────
  72.  WHAT WE WANT
  73. ─────────────────────────────────────────────────────────────────────────────
  74.  
  75. First lets ask ourselves, what would the perfect Vesa 2.0 mode setting
  76. library do for us? Well this is what we need:
  77.  
  78. A) Most important, we want usage of an LFB (Linear Frame Buffer). This
  79. allows us to write to video memory just as easy as writing to mode 13h.
  80. I read in imphobia that All PCI video cards support LFB, and most cards
  81. found on 486's support it, so requiring support for bank switched
  82. modes should not be neccessary (Thank god).
  83. B) We want to remap this LFB to usable memory. Most times the Vesa mode
  84. will work without doing this, but we should do this to get 100%
  85. compatibility.
  86. C) We also want good error detection. Like selecting an unavailable mode,
  87. and detecting to see if Vesa 2.0 is available.
  88. D) The interface should be  easy & intuitive. Instead of selecting a mode,
  89. we should pass an X resolution, Y resolution, and Bit Depth. Not only is this
  90. easier, but the vesa standard states that modes do not need be static. So in
  91. the future, mode 147h may not always be 320*240*32Bits.
  92. E) We want to receive as much information as possible. We want to know how
  93. many bits are R,G, and B, where they start, and what order they are in.
  94. we want to know how much available video memory there is, etc....
  95.  
  96. ─────────────────────────────────────────────────────────────────────────────
  97.  WHAT TO DO
  98. ─────────────────────────────────────────────────────────────────────────────
  99.  
  100. Okey, first, lets lay out the functions we are going to make:
  101.  
  102. -= VBEINFO  *vbeDetect(void) =-
  103. This will detect  to see if Vesa 2.0 is available, and return information
  104. on the video card.
  105.  
  106. -= long vbeGetModeInfo(int mode,VBEMODEINFO *bla) =-
  107. This will get every bit of info on a video mode, resolution, depth, video
  108. window stuff, bit organizing, etc... and return it into bla. It will return
  109. a 1 on success (Mode found, etc..) and 0 on failure.
  110.  
  111. -= VBESURFACE *vbeOpen(long X,long Y,long BPP) =-
  112. This will actually set the mode. It will set an X*Y*BPP mode (BPP being
  113. bits per pixel, not bytes). It will return a pointer to VBESURFACE,
  114. containing the location of LFB, the actual mode number, bits & bytes per
  115. pixel,etc...
  116.  
  117. -= vbeClose(VBESURFACE *bla) =-
  118. Of course we need to close the mode. This will get rid of all the vbe stuff,
  119. and return us to good old mode 3h.
  120.  
  121. -= vbeSetScanWidth(long width) =-
  122. This function will set the logical scanline width of video memory. This way
  123. we can set how far we can horizontally scroll. Remember, to set a pixel its
  124. (x+(y*logicalWidth)) not (x+(y*screenWidth)) Unless you make them the same.
  125. Which for starting out, we will. We will set this in pixels.
  126.  
  127. -= long vbeGetScanWidth(void) =-
  128. This function returns the logical scan width. We will get this in pixels.
  129.  
  130. -= vbeSetStart(long X,long Y) =-
  131. This will flip the screen to a certain X and Y position in video memory.
  132. Very usefull for page flipping and scrolling.
  133.  
  134. -= vbeGetStart(int *X, int *Y) =-
  135. This will return the screens logical X & Y position in video memory.
  136.  
  137. -= vbeVR() and vmode(int mode) =-
  138. Complimentary functions that wait for the vertical retrace (So there is no
  139. screen shearing) and set a standard vga mode respectively.
  140.  
  141. ─────────────────────────────────────────────────────────────────────────────
  142.  LETS START THE CODE
  143. ─────────────────────────────────────────────────────────────────────────────
  144.  
  145.  Please note, I will not list the structures here, as they are VERY commented
  146. in the code, and quite large. I also won't go through the code step by step,
  147. but rather explain what is happening. I would recommend either printing the
  148. code up, or having it on hand in another window.
  149.  Also note that we are going to be calling most functions through real mode,
  150. this is because many VBE functions require the real mode trait of passing
  151. pointers through ES:DI.
  152.  
  153. DPMI Interrupts
  154. ~~~~~~~~~~~~~~~
  155. First, I should probably list the DPMI interrupts we are going to use:
  156. (All DPMI interrupts use INT 31h)
  157.  
  158. -= Allocate Dos Memory =-
  159.   AX     = 0100h
  160.   BX     = # of paragraphs to allocate. (A paragraph is 16 bytes)
  161. Returns:
  162.   AX     = Real mode segment of Block.
  163.   DX     = Selector for the allocated block.
  164.   CF     = 0 on success,1 on error
  165.  
  166.   We are going to need this function to allocate memory for our information
  167. blocks. Like VBEINFO and such.
  168.  
  169.  
  170. -= Free Dos Memory =-
  171.   AX     = 0101h
  172.   DX     = Selector of Block
  173. Return
  174.   CF     = 0 on success, 1 on error
  175.  
  176. Free the memory we just allocated of course.
  177.  
  178.  
  179. -= Simulate Real Mode Interrupt =-
  180.   AX     = 0300h
  181.   BL     = Interrupt number
  182.   BH     = should be kept to 0.
  183.   CX     = Number of words to copy from protected to Real mode stack.
  184.   ES:DI  = selector:offset or RM structure (See RMREGS in asm code)
  185. Returns:
  186.   RMREGS = Filled with return info
  187.   CF     = 1 on error, 0 on success
  188.  
  189. We need this function to make real mode calls from protected mode.
  190.  
  191.  
  192. -= Physical Address Mapping =-
  193.   AX     = 0800h
  194.   BX:CX  = Physical address we want to map.
  195.   SI:DI  = Size we want to map
  196. Return:
  197.   CF     = 0 on success, 1 on error
  198.   BX:CX  = linear address that maps the memory
  199.  
  200. This function is very helpfull, because it lets us write to memory we
  201. normally wouldnt be able to reach. Since a video card mey be crazy
  202. enough to put its LFB out there ;).
  203.  
  204.  
  205. - Free Physical Address Mapping -
  206.   AX     = 0801h
  207.   BX:CX  = Address returned by function 0800h.
  208. Return
  209.   CF     = 0 on success, 1 on error.
  210.  
  211. Free up the memory we mapped, like the good coders we are =).
  212.  
  213. VBE Interrupts
  214. ~~~~~~~~~~~~~~
  215. Now that we have the DPMI interrupts out of the way, I will state the VBE
  216. interrupts we will be using. Remember that some  of them will be called
  217. through a real mode interrupt. All Vesa interrupts use INT 10h.
  218. VBE instructions will always return 04Fh in EAX. if a VBE function does not
  219. return this, it means there was an error (VBE driver not loaded and such).
  220.  
  221. -= Return VBE controller Info =-
  222.   AX     = 4F00h
  223.   ES:DI  = Pointer to 512 Allocated bytes to put VbeInfoBlock
  224.  
  225. This function will put a lot of info about the video card into a VbeInfoBlock
  226. pointed to by ES:DI (So it needs to be called from real mode).
  227. Remember to set VbeSignature inside VbeInfoBlock to 'VBE2'. This will tell
  228. the interrupt that we want vbe2.0 information returned. After the Int is
  229. called, 'VESA' should be returned in VBE Signature. To see everything
  230. returned, check the VbeInfoBlock structure in the code.
  231.  
  232.  
  233. -= Return VBE Mode Info =-
  234.   AX     = 4F01h
  235.   CX     = Mode Number
  236.   ES:DI  = Pointer to ModeInfoBlock structure.
  237.  
  238. This will fill up a ModeInfoBlock pointed to by ES:DI (also needs to be
  239. called from RM) with all sorts of goodies about the mode in CX. To see
  240. everything returned, please check ModeInfoBlock structure inside the code.  
  241.  
  242.  
  243. -= Set VBE Mode =-
  244.   AX     = 4F02h
  245.   BX     = Mode Number. Bits 9-13 must be 0. OR bit 14 with 1 to indicate we
  246.            want to use LFB. OR bit 15 with 1 to clear video memory.
  247.  
  248. Here is the Actual meat of the modeSetting. You will notice that there is no
  249. structure passed here. That is because all the info on the mode is obtained
  250. through Function 4F01h (Like LFB location and stuff).
  251. Notice that since we don't need to pass info through ES:DI this function can
  252. be called Directly.
  253.  
  254.  
  255. -= Get/Set Display Start =-
  256.   AX     = 4F07h
  257.   CX     = First Displayed Pixel Scanline (X pos)
  258.   DX     = First Displayed Scanline       (Y pos)
  259.   BH     = Must be kept to 0
  260.   BL     = 0 to set display, 1 to get display, 80h=Set during V. Retrace.
  261. Return:
  262.   AX     = VBE return status (Returned in ALL functions)
  263.   BH     = Always 00h.
  264.   CX     = First Displayed Pixel Scanline (On get display)
  265.   DX     = First Displayed Scanline       (On get display)
  266. Imagine the screen as a small rectangle, held completely inside a larger
  267. rectangle (video memory). This function will move the little rectangle around
  268. the big rectangle very smoothly. This allows such things as page flipping,and
  269. scrolling at very high speeds. This same function is also used to get the
  270. location of the screen in memory, by setting BL to 1.
  271.  
  272. -= Get/Set Logical Display Width =-
  273.   AX     = 4F06h
  274.   BX     = 0 to set width in pixels, 2 to set width in bytes,
  275.            1 to get width, 3 to get maximum width.
  276.   CX     = Width in pixels (Or bytes, depending upon BX) to set width.
  277. Return:
  278.   AX     = VBE return status (returned in ALL functions)
  279.   BX     = Width in bytes of scanline.
  280.   CX     = Width in pixels.
  281.   DX     = Maximum number of scanlines.
  282. This sets or gets the width we want the big rectangle of video memory holding
  283. our screen to be. This way we can scroll horizontally as well as vertically.
  284. The only problem with this is that finding Y coordinates varies with the
  285. logical scanline width. (PixelPos= x+(y*LogicalWidth))
  286.  
  287. ______________________
  288. Whats In The Functions
  289. ~~~~~~~~~~~~~~~~~~~~~~
  290. It feels good to get all those damn interrupts out of the way. Now I can
  291. safely explain all the functions in pseudocode. After this, you should be
  292. able to piece the actual ASM code together with this pseudocode quite
  293. smoothly.
  294.  
  295. -= VBEINFO  *vbeDetect(void) =-
  296. start:
  297.   'DPMI 100h' Get memory to put vbeInfo Block into
  298.   Ready RmRegs for 'VBE 4F00h'
  299.   Put VBE2 into vbeInfo.VbeSignature
  300.   'DPMI 300h' Call VBE 4F00h in real mode.
  301.   Check to see If everything ok.
  302.   'DPMI 101h' Free the vbeInfoBlock
  303. end:
  304.  
  305. -= int vbeGetModeInfo(int mode,VBEMODEINFO *bla) =-
  306. start:
  307.   call VbeDetect JIK
  308.   'DPMI 100h' Get memory to put modeInfo Block into
  309.   Ready RMREGS for 'VESA 4F01h'
  310.   'DPMI 300h' to call VBE 4f01h in real mode
  311.   move everything from modeInfo Block to bla
  312.   free modeInfo Block with 'DPMI 101h'
  313.   return Success
  314. End:
  315.  
  316. -= VBESURFACE *vbeOpen(int X,int Y,int BPP) =-
  317. start:
  318.   Make sure we arent already in a vesa mode
  319.   call VbeDetect JIK
  320.   'DPMI 100h' to allocate for ModeInfo block (To check every available mode)
  321.   Go through all available modes returned by VbeDetect until finding a match
  322.   OR the Mode found with 4000h to say we want LFB
  323.   If It worked, map the LFB memory to accessible memory with 'DPMI 800h'
  324.   Set vbeInit variable so from now on we know a mode is set
  325.   Make sure logical scanline width is equal to screen scanline width.
  326.   Set everything in the return structure
  327. end:
  328.  
  329. -= vbeClose(VBESURFACE *bla) =-
  330. start:
  331.   Check to see if a vbe mode is set
  332.   Free the mapped LFB memory with 'DPMI 801h'
  333.   Set VGA mode 0x3h
  334. end:
  335.  
  336. Almost direct functions:
  337. -= vbeSetScanWidth(int width)  =-
  338.    Set logical screen width in pixels, with 'VBE 4F06h'
  339. -= int vbeGetScanWidth( void)  =-
  340.    Get logical screen width in pixels, with 'VBE 4F06h'
  341. -= vbeGetStart(int *X, int *Y) =-
  342.    Get logical screen pos with 'VBE 4f07h'
  343. -= vbeSetStart(int  X, int  Y) =-
  344.    Set logical screen pos with 'VBE 4f07h'
  345.  
  346.  
  347.  
  348. We are done with the Code!
  349. ~~~~~~~~~~~~~~~~~~~~~~~~~~
  350.  Well, you should be able to piece everything together by now. If not, don't
  351. worry, take a breather and read over a nice refreshing 386 asm manual with a
  352. nice glass of pepsi.
  353.  
  354.  
  355. ─────────────────────────────────────────────────────────────────────────────
  356.  NOW HOW DO I PUT THE CODE IN?
  357. ─────────────────────────────────────────────────────────────────────────────
  358.  
  359. Now that you have the asm at hand, and understand it, it is time to get using
  360. Vesa 2.0. First, lets get the thing to compile. It should go in as easy as
  361. a snap of your fingers, just include the ASM in your makefile, or the .OBJ
  362. in your project file (Or .asm if the project manager is set to a compatible
  363. assembler). After that, just include the .h in your C files. If you want to
  364. use the functions in other ASM programs, make sure to mark them as External
  365. wherever you use them.
  366. If you get any troubles with tasm, the switches I use are:
  367.  tasm  -q -p -t -ml -zi -m3 vgovbe20
  368. To compile the simple C example file, if you have Watcom, you can run
  369. M.bat and then run test.exe.
  370.  
  371. ─────────────────────────────────────────────────────────────────────────────
  372.  COOL! IT COMPILES! NOW HOW DO I USE THEM?
  373. ─────────────────────────────────────────────────────────────────────────────
  374.    Well, ill explain how in C (Im sure everyone who uses ASM can figure this
  375. out ;). First off, you probably want to call vbeDetect, to see if everything
  376. is in there fine.
  377.   After that, we can set any mode with ease. Just make sure to have
  378. VBESURFACE *myScreen; defined. (Make sure to see the VBESURFACE struct
  379. in the .H file).
  380. After that, just call myScreen = vbeOpen(X,Y,BPP);
  381. X=The x resolution you want, Y=duh, BPP is the bits per pixel to use.
  382.  
  383. --BPP can normally be one of:
  384. 4  = 16 palleted colors,
  385. 8  = 256 palleted colors,
  386. 15 = 5.5.5.1 RGBA colors.
  387. 16 = (Arbitrary, but I think UniVBE always sets this to 5.6.5) RGB colors
  388. 24 = 8.8.8 RGB Colors.
  389. 32 = 8.8.8.8 RGBA colors.
  390.  
  391. To actually plot a pixel is as simple as writing to mode 13h, except the
  392. screen isnt static at 0A0000h. Just get the screen pointer from myScreen.LFB;
  393. after that, you are free to play around =).
  394.  
  395. --Lets do a few Experiments with High/True color:
  396. Remember how in paletted 13h to write a white pixel, you would get whatever
  397. palette entry was white and write that? Well now you basically write that
  398. palette straight to the screen.
  399. In 24bit mode, the screen is layed out as:
  400. byte =0,1,2,3,4,5,6,7,8                957,958,959
  401.      |B G R|B G R|B G R|...............|B   G   R|
  402. pixel=  1  ,  2  ,  3  ,                   319
  403.  
  404. So, to write a white pixel to the screen in 24 bit value, you would do:
  405. (char *)(myScreen)[0]=255; //Write Blue value of pixel 0
  406. (char *)(myScreen)[1]=255; //Write Green value of pixel 0
  407. (char *)(myScreen)[2]=255; //Write Red value of pixel 0
  408. //Next pixel starts at [3], if 32bit mode, next pixel would be at [4].
  409.  
  410. You probably noticed 2 things. One is that the screen is layed out with first
  411. byte being B, then G, then R (Instead of RGB) (Some cards have the ability to
  412. flip this around, but I have never come across this, same as non 565 16bit
  413. modes. just to be safe, check the mode after you set it). Another thing is
  414. that 24bit mode is a bitch. It's no fun having to write byte by byte.
  415.  Thats why 32Bit mode was invented, it is much faster, because you can write
  416. a Dword at a time, except you have that Alpha byte at the end. (An alpha byte
  417. is a padding byte, this byte doesnt neccessarilly need to be wasted memory,
  418. You can store many things in here if you put your mind to it).
  419. Anyways, to set a white pixel in 32bit mode, you can do this:
  420. (long *)(myScreen)[0] = 00FFFFFFh
  421. Whats real cool, is that you can set the pixel real easy in hex, by splitting
  422. the number up like so:
  423.  |00 |FF |FF |FF |
  424.    A   R   G   B   
  425. To use high color (15/16 bit modes) Is a tiny bit trickier, but if you use
  426. them right, they can actually be faster since there is much less data to
  427. move.
  428. A white pixel in 16BIT mode= (short *)(myScreen)[0] = FFFFh
  429. and 15bit mode= (short *)(myScreen)[0] = 7FFFh (can also be FFFFh).
  430. The formula to convert a 24bit pixel to a 16bit pixel is:
  431. (short *)(myScreen)[0] = ((char *)(yourScreen)[0]>>3)    |
  432.                         (((char *)(yourScreen)[0]<<3)&7E)| 
  433.                         (((char *)(yourScreen)[0]<<8)&F8);
  434. It may seem annoying at first, but once you get it integrated into your
  435. functions it starts to become automatic. (Just don't call a 24to16bit
  436. conversion every pixel!)
  437. One last cool thing I want to mention, is that you can do REAL fast 50%
  438. transparencies in True/High color using bit-wise operations. Simply do this:
  439. For 32Bit mode:
  440. --------
  441. //PixelA = source pixel. PixelB=Destination pixel
  442. pixelA >>=1;  //Divide the pixel values in half
  443. pixelB >>=1;
  444. pixelA &=0x7F7F7F7F;  //Clear the residual bit
  445. pixelB &=0x7F7F7F7F;
  446. //By now pixelA & Bs maximum R,G,and B values are 7F=127 out of 255.
  447. pixelB +=pixelA;
  448. //Now pixelB is equal to A+B transparency.
  449. -------
  450.  
  451. For 16Bit mode:
  452. --------
  453. //PixelA = source pixel. PixelB=Destination Pixel
  454. pixelA >>=1;  //Divide the pixel Values in half
  455. pixelB >>=1;
  456. pixelA &=0x7FEB;  //Clear the residual bit
  457. pixelB &=0x7FEB;
  458. //By now pixelA & Bs maximum R,G,and B values are 7F=127 out of 255.
  459. pixelB +=pixelA;
  460. //Now pixelB is equal to A+B transparency.
  461. -------
  462.  
  463. With this you can do many effects, such as Motion Blur (By recursively making
  464. one screen transparent over the other with 2 screen buffers, and fliping
  465. which one you write to). Or quick transparencies.There are many other effects
  466. you can do with bitwise operations, Enjoy =). Thanks very much to Brazil for
  467. showing me this previous technique when I started Vesa coding last year.
  468.  
  469.  
  470. ─────────────────────────────────────────────────────────────────────────────
  471.  WELL, IM ALL SET TO GO, ANYTHING ELSE I SHOULD BE AWARE OF?
  472. ─────────────────────────────────────────────────────────────────────────────
  473.  
  474. Yes actually, a few things:
  475. A) Even though it's not neccessary, you should do a vbeGetModeInfo mode after
  476. you set a mode, do this to ensure a few things: If you are doing a 16bit mode
  477. to, see if it's 5.6.5(if not either quit, or adjust your functions) And check
  478. to see if the screen is ordered BGR not the other way around. I have actually
  479. never encountered these problems, but there are cards that have options to
  480. change this, and VBE specs say it is liable to happen. (Although I think
  481. UNIVBE always makes this BGR & 5.6.5)
  482. B) Under most cases, write to an Offscreen buffer and copy to screen. This
  483. is because reading from video memory is PAINFULLY slow. Here is where the
  484. biggest benefits of using 16bit VS 32bit pay off.
  485. C) If you are going to clear the screen, I have found it much faster to clear
  486. with the FPU. Although copying with FPU seems to be slower (Because of
  487. reading Invalid FPU numbers (NaN)). Try and see, different people get
  488. different results.
  489. D) UniVBE is actually real nice, It does many things for you like make sure
  490. LFBs are Always available, for any and every card. It also makes sure 16bit
  491. modes are always 5.6.5 and data is organized in BGR fashion. Univbe does have
  492. an option for switching this... but thats the users fault ;). 
  493.  
  494.  
  495. ─────────────────────────────────────────────────────────────────────────────
  496.  HOW COULD I MAKE THIS VBE20 LIBRARY BETTER?
  497. ─────────────────────────────────────────────────────────────────────────────
  498.  
  499. Well, many ways. I originally set this document to teach VBE mode setting
  500. only (VBE function 4f07h was just a bonus ;). There are still many ways you
  501. can make this better:
  502. A)  We had an A), but we put this in for you, ain't that sweet? =).
  503. B)  Get support for VBE/AF (accelerator functions) in there. Unfortunately
  504. we haven't been able to try these out since uniVBE currently only provides
  505. this for the MACH64 video card. These functions should allow us to use
  506. 3D and 2D accelleration features as easily (?) as setting vesa modes are now.
  507. C)  Actually make it a library ;) This is by far not complete. Add function
  508. pointers to different 2D primitives according to the mode. Or go full steam
  509. ahead and make a full OOP engine. The sky is the limit.
  510.  
  511.  
  512. ─────────────────────────────────────────────────────────────────────────────
  513.  THE LAST WORD
  514. ─────────────────────────────────────────────────────────────────────────────
  515.  
  516.  It's now 5:30AM and I haven't slept for like 24 hours, so I better go get
  517. some coffee and stay awake... just not writing tutorials where not writing
  518. coherently can make universes collide. Wow... the keys on my keyboard look
  519. all fuzzy and wavy... must 7BEF em...  This is the reason there were no
  520. ASCII pictures in here =). Hopefully the descriptions where good enough
  521. where you did not need them.
  522.  If you got any use out of this Tutorial or this code, make sure to email us
  523. and/or greet us in your productions, it's all we ask =). If you want more
  524. information on the VBE, make sure to download the oficial VBE specs at
  525. www.scitechsoft.com and many other popular places. If you want more help,
  526. I have released the source to my truecolor 4K intro 'Faith', which should be
  527. available on hornet (ftp.cdrom.com/pub/demos). This intro shows how to do
  528. more advanced true-color tricks than the included test.c.
  529.  Finally I want to thank TimJ for giving me the original VBE code way back,
  530. which helped me through a lot of bugs that would have taken a long time to
  531. figure out otherwise. All the attached code was done by him, and without it,
  532. this DOC probably wouldn't have existed.
  533.  
  534.   Greets:
  535.     Everyone else In Vertigo, Vastator the typo tamer(Just a little too late)
  536.     Midnight, Fysx, Phred, GooRoo,  Vor, Brazil, God, MrData, Grimace...
  537.   These fly out to many people, please check the our web pages greet list,
  538.   being greeted in there is just as good as being greeted in all of our
  539.   productions ;).
  540.  
  541. Peace & Werd or something...
  542.    Vector/Vertigo
  543.